﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace AisinGioro.Server.Hubs
{
    using Notify;

    public class WorkItemFamily
    {
        protected ICollection<WorkItem> _collection;
        protected INotify _notify;

        public WorkItemFamily()
        {
            _collection = new List<WorkItem>();
            _notify = NotifyBase.GetInstance();
        }

        public int Count
        {
            get { return _collection.Count; }
        }

        /// <summary>
        /// 添加监控项（不存才添加）
        /// </summary>
        public void Add(string itemKey)
        {
            if (!this.Exists(itemKey))
            {
                _collection.Add(new WorkItem(itemKey));
            }
        }
        /// <summary>
        /// 添加多个监控项（不存才添加）
        /// </summary>
        public void AddRange(IEnumerable<string> itemKeys)
        {
            foreach(var itemKey in itemKeys)
            {
                this.Add(itemKey);
            }
        }
        public bool Exists(string itemKey)
        {
            return _collection.Any(i => i.Key == itemKey);
        }
        public void Clear()
        {
            _collection.Clear();            
        }

        public WorkItem this[int index]
        {
            get
            {
                return _collection.ElementAt(index);
            }
        }
        public WorkItem this[string itemKey]
        {
            get
            {
                return _collection.FirstOrDefault(i => i.Key == itemKey);
            }
        }

        /// <summary>
        /// 指定监控项签到（不存在则添加）
        /// </summary>
        public void SignIn(string itemKey)
        {
            if (this.Exists(itemKey))
                this[itemKey].LastSignedIn = DateTime.Now;
            else
                this.Add(itemKey);
        }
        
        /// <summary>
        /// 遍历监控项列表
        /// </summary>
        public void ForEach(Func<WorkItem, bool> predicate, Action<WorkItem> action)
        {
            foreach (var item in predicate == null ? _collection : _collection.Where(predicate))
            {
                if (action != null)
                    action(item);
            }
        }

        /// <summary>
        /// 异步发送通知消息
        /// </summary>
        public async void SendNotifyAsync(string itemKey, string message)
        {
            //itemKey format:
            //Web-Windows-10.3.174.171
            //Web-Windows-10.3.174.171@Cpu
            //Web-Windows-10.3.174.171@Mem
            //Web-Windows-10.3.174.171@Disk@C
            //Web-Windows-10.3.174.171@Conn@SiteName
            //vvzkH
            try
            {
                if (!_notify.Enabled) return;

                var tempWorkItem = this[itemKey];
                //指定监控项是否可以发送通知（监控项异常时，默认2分钟内只发送一次通知）
                if (tempWorkItem.LastNotified.AddMinutes(2) > DateTime.Now)
                    return;

                tempWorkItem.LastNotified = DateTime.Now;
                string result = await _notify.SendMsg(message);
                Core.LogHelper.Warn("SendNotify[{0}] {1}", _notify.GetType().Name, message);                
            }
            catch (Exception ex)
            {
                Core.LogHelper.Error("SendNotify[Error] {0}", ex.Message);
            }
        }
    }

    /// <summary>
    /// 监控项（主机CPU/内存/磁盘/连接数/ping/port/http等）
    /// </summary>
    public class WorkItem
    {
        public string Key { get; set; }
        public DateTime LastSignedIn { get; set; }  //上次签到
        public DateTime LastNotified { get; set; }  //上次通知

        public WorkItem()
        {
            this.LastSignedIn = DateTime.Now;
            this.LastNotified = DateTime.Now.AddMinutes(-2);
        }
        public WorkItem(string itemKey) : this()
        {
            this.Key = itemKey;
        }
    }
}
